{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Data Science in Python (DSiP) - Programming Basics\n",
    "\n",
    "by [Michael Granitzer (michael.granitzer@uni-passau.de)](http://www.mendeley.com/profiles/michael-granitzer/) \n",
    "\n",
    "   \n",
    "based on the following sources\n",
    "\n",
    "* [J.R. Johansson (robert@riken.jp)](http://dml.riken.jp/~rob/), \n",
    "  [Scientific Programming in Pyton](http://github.com/jrjohansson/scientific-python-lectures)\n",
    "\n",
    "__License__\n",
    "\n",
    "This work is licensed under a [Creative Commons Attribution 3.0 Unported License](http://creativecommons.org/licenses/by/3.0/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Python Files and Modules"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Python Files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_number": 3,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "__Structure of the Code file__\n",
    "    \n",
    "* Code files end with \"`.py`\":\n",
    "\n",
    "        myprogram.py\n",
    "\n",
    "* Every line is a Python statement (or part thereof). \n",
    "\n",
    "        * comment line start with `#`\n",
    "\n",
    "__Run Python Program from command line__\n",
    "\n",
    "* Execute with python interpreter\n",
    "\n",
    "        $ python myprogram.py        \n",
    "\n",
    "* Direct use on UNIX systems\n",
    "    - define the path to the interpreter on the first line of the program as __comment__\n",
    "\n",
    "        \\#!/usr/bin/env python\n",
    "        \n",
    "\n",
    "    - If setting the executable flag of the file, we can run the program directly in the shell:\n",
    "\n",
    "        $ myprogram.py\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 3,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Python Modules"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 5,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "### Overview\n",
    " * **Modules** group Python functions\n",
    " * __Modules are files__ with containing Python code (e.g. myprogram.py)\n",
    " * **Using Modules** requires to import them first using the __`import` statement__\n",
    " * **Scope:** Import a module to the current namespace, defined in its own namespace or used as `module.function`\n",
    " \n",
    "The Python Standard Library is a large collection of modules that provides *cross-platform* implementations of common facilities such as access to the operating system, file I/O, string management, network communication, and much more.\n",
    "\n",
    "### References\n",
    " \n",
    " * The Python Language Reference: http://docs.python.org/2/reference/index.html\n",
    " * The Python Standard Library: http://docs.python.org/2/library/"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 5,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Module import\n",
    "\n",
    "For example, to import the module `math`, which contains many standard mathematical functions, we can do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 7
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "import math"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 8
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Imports the **whole module** and makes it available under **the moduls namespace**. For example, we can do:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 9,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "\n",
    "x = math.cos(2 * math.pi)\n",
    "\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 9,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "<img src=\"files/images/python namespaces.png\" width=\"60%\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 11,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "<div class=\"alert alert-warning\">\n",
    "**Note**: Contrary to Java a Python file can contain classes, variables, function and main code. The filename defines the module name and the namespace to access the functions\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 11,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Import a Module in current Namespace\n",
    "\n",
    "* Goal: avoid writing the prefix `module.` by __importing all symbols (functions and variables)__ of one module into the current namespace "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 13
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0\n"
     ]
    }
   ],
   "source": [
    "from math import *\n",
    "\n",
    "x = cos(2 * pi)\n",
    "\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 13,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "* **Caveat:** possible namespace conflicts in large programs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 13,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Import selected Functions into the current Namespace \n",
    "\n",
    "Selective import of function from a module"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 16
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0\n"
     ]
    }
   ],
   "source": [
    "from math import cos, pi\n",
    "\n",
    "x = cos(2 * pi)\n",
    "\n",
    "print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 17
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "### Changing the Name/Namespace of a Functions/Modules at Import\n",
    "Names of variables, functions and the namespace of moduls can be changed at  import using the **`as`** keyword"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 18
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0 1.0\n"
     ]
    }
   ],
   "source": [
    "from math import cos as c\n",
    "from math import pi as p\n",
    "import math as m\n",
    "x = c(2 * p)\n",
    "y = m.cos(2 * m.pi)\n",
    "print (x,y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 18,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "**Caveat:** Readability may suffer."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 18,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Looking at what a module contains\n",
    "\n",
    "Once a module is imported, we can list the symbols it provides using the `dir` function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 21,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']\n"
     ]
    }
   ],
   "source": [
    "import math\n",
    "\n",
    "print(dir(math))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 21,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Getting Help on a Function\n",
    "\n",
    "And using the function `help` we can get a description of each function (almost .. not all functions have docstrings, as they are technically called, but the vast majority of functions are documented this way). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 23
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function log in module math:\n",
      "\n",
      "log(...)\n",
      "    log(x[, base])\n",
      "    \n",
      "    Return the logarithm of x to the given base.\n",
      "    If the base not specified, returns the natural logarithm (base e) of x.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(math.log)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 24
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2.302585092994046"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "log(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 25,
     "slide_helper": "subslide_end"
    },
    "scrolled": false,
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "math.log(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 25,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Getting Help on a Module\n",
    "\n",
    "Use `help` function directly on modules: \n",
    "\n",
    "    help(math) \n",
    "\n",
    "Some very useful modules form the Python standard library are \n",
    "\n",
    " * `os`\n",
    " * `sys`\n",
    " * `math`\n",
    " * `shutil`\n",
    " * `re`\n",
    " * `subprocess`\n",
    " * `multiprocessing`\n",
    " * `threading`. \n",
    "\n",
    "A complete lists of standard modules for Python 2 and Python 3 are available at http://docs.python.org/2/library/ and http://docs.python.org/3/library/, respectively."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 25,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Exercise: Explore the math package\n",
    "\n",
    "**Setup**\n",
    "\n",
    " * Open the Jupyter notebook using the command `'jupyter notebook'` from the directory where you want to store your exercises\n",
    " * Create a new notebook - use a meaningfull naming scheme, like for example `'Name-coursname-semester'`\n",
    " * Create a first markdown block and create a header with title, name, course and semester\n",
    " * Work through the ipython notebook tutorial under http://ipython.org/ipython-doc/2/notebook/notebook.html (Yes, that's for the \"old\" ipython notebook, but tutorial is better than the port to Jupyter.) \n",
    "   - Learn the principles behind the notebook, how it is started, how you edit code and text and the ipytyhon magic commands\n",
    " * Create a first code block and start with the following exercise\n",
    " \n",
    "** Exercise **\n",
    "\n",
    "Explore the math package and make the following calculations\n",
    "\n",
    "* `cos(0.7) + sin(0.3)`\n",
    "* factorial of 20\n",
    "* round down the following numbers: `1.4`, `3.5`, `4.8`\n",
    "* check the run-time behaviour of different functions in the `math` package "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 25,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "scrolled": true,
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']\n",
      "Help on built-in function cos in module math:\n",
      "\n",
      "cos(...)\n",
      "    cos(x)\n",
      "    \n",
      "    Return the cosine of x (measured in radians).\n",
      "\n",
      "None\n",
      "Help on built-in function sin in module math:\n",
      "\n",
      "sin(...)\n",
      "    sin(x)\n",
      "    \n",
      "    Return the sine of x (measured in radians).\n",
      "\n",
      "None\n",
      "Help on built-in function factorial in module math:\n",
      "\n",
      "factorial(...)\n",
      "    factorial(x) -> Integral\n",
      "    \n",
      "    Find x!. Raise a ValueError if x is negative or non-integral.\n",
      "\n",
      "None\n",
      "Help on built-in function floor in module math:\n",
      "\n",
      "floor(...)\n",
      "    floor(x)\n",
      "    \n",
      "    Return the floor of x as an Integral.\n",
      "    This is the largest integer <= x.\n",
      "\n",
      "None\n",
      "1.154260529593139\n",
      "2432902008176640000\n",
      "[1, 3, 4]\n",
      "112 ns ± 1.79 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n",
      "97.2 ns ± 2.78 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n"
     ]
    }
   ],
   "source": [
    "import math as m\n",
    "\n",
    "print(dir (m))\n",
    "print(help(m.cos))\n",
    "print(help(m.sin))\n",
    "print(help(m.factorial))\n",
    "print(help(m.floor))\n",
    "\n",
    "print(m.cos(0.7) + m.sin(0.4))\n",
    "print(m.factorial(20))\n",
    "print([m.floor(i) for i in [1.4,3.5,4.8]])\n",
    "\n",
    "%timeit m.factorial(20) \n",
    "%timeit m.cos(0.7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 25,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Variables and Types in Python"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 25,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Syntax and Naming Convention"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 31,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    " * __Variable names__ contain \n",
    "    * alphanumerical characters `a-z`, `A-Z`, `0-9` \n",
    "    * some special characters such as `_`. \n",
    "   \n",
    "\n",
    " * __ Convention __ \n",
    "     * variable names start with a lower-case letter\n",
    "     * Class names start with a capital letter. \n",
    "     * **Visible variable** names must start with a letter. \n",
    "     * **Hidden variables** and class variables start with a double underscore`__`\n",
    "     \n",
    "\n",
    " * __Python keywords__ not usable as variable names:\n",
    " \n",
    " \n",
    "    and, as, assert, break, class, continue, def, del, elif, else, except, \n",
    "    exec, finally, for, from, global, if, import, in, is, lambda, not, or,\n",
    "    pass, print, raise, return, try, while, with, yield\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 31,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Assignment"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 31
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "The assignment operator in Python is **`=`**. \n",
    "\n",
    "The type is determined **dynamically** on assignment. No explicit definition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 34
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "# variable assignments\n",
    "x = 1.0\n",
    "my_variable = 12.2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 35
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "The type is derived form the value it was assigned (duck-typing)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 36,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "float"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 36,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "If we assign a new value to a variable, its type can change."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 38
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "x = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 39
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "type(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 40
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "If we try to use a variable that has not yet been defined we get an `NameError`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 41,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'z' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-29-0a08d1e4f346>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mz\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'z' is not defined"
     ]
    }
   ],
   "source": [
    "print(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 41,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Basictypes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 43
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "int"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# integers\n",
    "x = 1\n",
    "type(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 44
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "float"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# float\n",
    "x = 1.0\n",
    "type(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 45
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "bool"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# boolean\n",
    "b1 = True\n",
    "b2 = False\n",
    "\n",
    "type(b1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 46
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "complex"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# complex numbers: note the use of `j` to specify the imaginary part\n",
    "x = 1.0 - 1.0j\n",
    "type(x  )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 47
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1-1j)\n"
     ]
    }
   ],
   "source": [
    "print(x )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 48,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0 -1.0\n"
     ]
    }
   ],
   "source": [
    "print(x.real, x.imag)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 48,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Type utility functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 48
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "The module `types` contains a number of type name definitions that can be used to test if variables are of certain types:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 51
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['AsyncGeneratorType', 'BuiltinFunctionType', 'BuiltinMethodType', 'CodeType', 'CoroutineType', 'DynamicClassAttribute', 'FrameType', 'FunctionType', 'GeneratorType', 'GetSetDescriptorType', 'LambdaType', 'MappingProxyType', 'MemberDescriptorType', 'MethodType', 'ModuleType', 'SimpleNamespace', 'TracebackType', '_GeneratorWrapper', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_ag', '_calculate_meta', '_collections_abc', '_functools', 'coroutine', 'new_class', 'prepare_class']\n"
     ]
    }
   ],
   "source": [
    "import types\n",
    "\n",
    "# print all types defined in the `types` module\n",
    "print(dir(types))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 52
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = 1.\n",
    "\n",
    "# check if the variable x is a float\n",
    "type(x) is float"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 53,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# check if the variable x is an int\n",
    "type(x) is int"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 53,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "We can also use the `isinstance` method for testing types of variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 55,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "isinstance(x, float)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 55,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Type casting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 57
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.5 <class 'float'>\n"
     ]
    }
   ],
   "source": [
    "x = 1.5\n",
    "\n",
    "print(x, type(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 58
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 <class 'int'>\n"
     ]
    }
   ],
   "source": [
    "x = int(x)\n",
    "\n",
    "print(x, type(x))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 59
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1+0j) <class 'complex'>\n"
     ]
    }
   ],
   "source": [
    "z = complex(x)\n",
    "\n",
    "print(z, type(z))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 60,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "float(z.imag)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 60,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### Complex Numbers\n",
    "\n",
    "Complex variables cannot be cast to floats or integers. We need to use `z.real` or `z.imag` to extract the part of the complex number we want:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 62,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0  ->  True <class 'bool'>\n",
      "0.0  ->  False <class 'bool'>\n"
     ]
    }
   ],
   "source": [
    "y = bool(z.real)\n",
    "\n",
    "print(z.real, \" -> \", y, type(y))\n",
    "\n",
    "y = bool(z.imag)\n",
    "\n",
    "print(z.imag, \" -> \", y, type(y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 62,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Operators and Comparisons"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 62,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "Most operators and comparisons in Python work as one would expect. We will briefly outline the following operators\n",
    "\n",
    " * Arithmetic Operators\n",
    " * Boolean Operators \n",
    " * Comparison Operators\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 62,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Arithmetic Operators"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 62
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "* Arithmetic operators `+`, `-`, `*`, `/`, `//` (integer division), '**' power\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 67
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, -1, 2, 0.5)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1 + 2, 1 - 2, 1 * 2, 1 / 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 68
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3.0, -1.0, 2.0, 0.5)"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "1.0 + 2.0, 1.0 - 2.0, 1.0 * 2.0, 1.0 / 2.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 69
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Integer division of float numbers\n",
    "3.0 // 2."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 70,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Note! The power operators in python isn't ^, but **\n",
    "2 ** 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 70,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Boolean Operators "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 70
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "* The boolean operators are spelled out as words `and`, `not`, `or`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 73
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True and False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 74
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "not False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 75,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True or False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 75,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Comparison Operators"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 75
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "* Comparison operators `>`, `<`, `>=` (greater or equal), `<=` (less or equal), `==` equality, `is` identical."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 78
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, False)"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 > 1, 2 < 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 79
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(False, False)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 > 2, 2 < 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 80
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, True)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 >= 2, 2 <= 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 81
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# equality\n",
    "[1,2] == [1,2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 82
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 3]\n"
     ]
    }
   ],
   "source": [
    "# objects identical?\n",
    "l1 = [1, 2]\n",
    "l2 = [1,2]\n",
    "l1 = l2\n",
    "l2[1] = 3\n",
    "l1 is l2\n",
    "print(l1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 83,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[1,2] is [1,2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 83,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Basic Data Structures "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 83,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "Python provides a large set of fast, easy to use data structures. In particular\n",
    "\n",
    " * Strings\n",
    " * List  (mutable arrays)\n",
    " * Tupel (inmutable Lists)\n",
    " * Dictionaries (Maps)\n",
    " \n",
    "Built-in data structures are implemented in C.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 83,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Strings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 87
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "\n",
    "Strings are the variable type that is used for storing text messages as array of characters/bytes. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 88
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "str"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s = \"Hello world\"\n",
    "type(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 89
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# length of the string: the number of characters\n",
    "len(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 90
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello test\n"
     ]
    }
   ],
   "source": [
    "# replace a substring in a string with somethign else\n",
    "s2 = s.replace( \"world\", \"test\")\n",
    "print(s2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 91
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "We can index a character in a string using `[]`: \n",
    "\n",
    "**Note:** Indexing start at 0!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 92,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'H'"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 92,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Basic Indexing\n",
    "\n",
    "We can extract a part of a string using the syntax `[start:stop]`, which extracts characters between index `start` and `stop`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 94
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello'"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[0:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 95
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "If we omit either (or both) of `start` or `stop` from `[start:stop]`, the default is the beginning and the end of the string, respectively:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 96
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello'"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 97
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'world'"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[6:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 98,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello world'"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 98,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Advanced Indexing using :\n",
    "Define the step size using the syntax **`[start:end:step]`** (the default value for `step` is 1, as we saw above):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 100
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello world'"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[::1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 101
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hlowrd'"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s[::2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 102
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "This technique is called *slicing*. Read more about the syntax here: http://docs.python.org/release/2.7.3/library/functions.html?highlight=slice#slice"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 103,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Python has a very rich set of functions for text processing. See for example http://docs.python.org/2/library/string.html for more information."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 103,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### String formatting examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 105
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "str1 str2 str3\n"
     ]
    }
   ],
   "source": [
    "print(\"str1\", \"str2\", \"str3\")  # The print statement concatenates strings with a space"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 106
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "str1 1.0 False (-0-1j)\n"
     ]
    }
   ],
   "source": [
    "print(\"str1\", 1.0, False, -1j)  # The print statements converts all arguments to strings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 107
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "str1str2str3\n"
     ]
    }
   ],
   "source": [
    "print(\"str1\" + \"str2\" + \"str3\") # strings added with + are concatenated without space"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 108
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "value = 1.000000\n"
     ]
    }
   ],
   "source": [
    "print(\"value = %f\" % 1.0)       # we can use C-style string formatting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 109
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "value1 = 3.14. value2 = 1\n"
     ]
    }
   ],
   "source": [
    "# this formatting creates a string\n",
    "s2 = \"value1 = %.2f. value2 = %d\" % (3.1415, 1.5)\n",
    "\n",
    "print(s2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 110,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "value1 = 3.1415, value2 = 1.5\n"
     ]
    }
   ],
   "source": [
    "# alternative, more intuitive way of formatting a string \n",
    "s3 = 'value1 = {0}, value2 = {1}'.format(3.1415, 1.5)\n",
    "\n",
    "print(s3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question\n",
    "Print the last element of a given string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "word =\"Have fun\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Write your code here to print the last character\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "code_folding": [],
    "hideCode": false
   },
   "source": [
    "Execute the next cell to see a sample solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "hideCode": true,
    "hideOutput": false,
    "hidePrompt": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "You can access the last charactere of string by using negative indexing, the next instruction will let you print the last charactere\n",
      "\n",
      "    print(word[-1])\n",
      "\n",
      "\n",
      " You can also use the length of the string to access the last element\n",
      " since the indexing start from '0' so the length of the phrase minus one give us the index of the last element \n",
      " that's why len(word)-1 is the index of the last element \n",
      "    \n",
      "    print(word[len(word)-1])\n"
     ]
    }
   ],
   "source": [
    "print('''\n",
    "You can access the last charactere of string by using negative indexing, the next instruction will let you print the last charactere\n",
    "\n",
    "    print(word[-1])\n",
    "\n",
    "\n",
    " You can also use the length of the string to access the last element\n",
    " since the indexing start from '0' so the length of the phrase minus one give us the index of the last element \n",
    " that's why len(word)-1 is the index of the last element \n",
    "    \n",
    "    print(word[len(word)-1])''')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 110,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## List"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 110
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "Lists are very similar to strings, except that __each element can be of any type.__\n",
    "\n",
    "The syntax for creating lists in Python is `[...]`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 113
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'list'>\n",
      "[1, 2, 3, 4]\n"
     ]
    }
   ],
   "source": [
    "l = [1,2,3,4]\n",
    "\n",
    "print(type(l))\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 114,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "See `help(list)` for more details, or read the online documentation "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 114,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### List Indexing \n",
    "We can use the __same slicing techniques__ to manipulate lists as we could use on __strings__:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 116
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4]\n",
      "[2, 3]\n",
      "[1, 3]\n"
     ]
    }
   ],
   "source": [
    "print(l)\n",
    "\n",
    "print(l[1:3])\n",
    "\n",
    "print(l[::2])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 117
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "**Noe:** Indexing starts at 0!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 118,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "l[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 118,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Heterogeneous Types and Nesting\n",
    "Elements in a list do not all have to be of the same type:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 120
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 'a', 1.0, (1-1j)]\n"
     ]
    }
   ],
   "source": [
    "l = [1, 'a', 1.0, 1-1j]\n",
    "\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 121
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Python lists can be inhomogeneous and arbitrarily nested:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 122,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, [2, [3, [4, [5]]]]]"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "nested_list = [1, [2, [3, [4, [5]]]]]\n",
    "\n",
    "nested_list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 122,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Lists and flow control\n",
    "\n",
    "Lists play a very important role in Python, and are for example used in loops and other flow control structures (discussed below). There are number of convenient functions for generating lists of various types, for example the `range` function:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 124
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "range(10, 30, 2)"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "start = 10\n",
    "stop = 30\n",
    "step = 2\n",
    "\n",
    "range(start, stop, step)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 125
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[10, 12, 14, 16, 18, 20, 22, 24, 26, 28]"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# in python 3 range generates an iterator, which can be converted to a list using 'list(...)'. It has no effect in python 2\n",
    "list(range(start, stop, step))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 126
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(-10, 10))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 127
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello world'"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 128
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# convert a string to a list by type casting:\n",
    "\n",
    "s2 = list(s)\n",
    "\n",
    "s2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 129,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[' ', 'H', 'd', 'e', 'l', 'l', 'l', 'o', 'o', 'r', 'w']\n"
     ]
    }
   ],
   "source": [
    "# sorting lists\n",
    "s2.sort()\n",
    "\n",
    "print(s2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 129,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Adding, inserting, modifying, and removing elements from lists"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 131
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['A', 'd', 'd']\n"
     ]
    }
   ],
   "source": [
    "# create a new empty list\n",
    "l = []\n",
    "\n",
    "# add an elements using `append`\n",
    "l.append(\"A\")\n",
    "l.append(\"d\")\n",
    "l.append(\"d\")\n",
    "\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 132
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "We can modify lists by assigning new values to elements in the list. In technical jargon, lists are *mutable*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 133
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['A', 'p', 'p']\n"
     ]
    }
   ],
   "source": [
    "l[1] = \"p\"\n",
    "l[2] = \"p\"\n",
    "\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 134,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['A', 'd', 'd']\n"
     ]
    }
   ],
   "source": [
    "l[1:3] = [\"d\", \"d\"]\n",
    "\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 134,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### Insert\n",
    "\n",
    "Insert an element at an specific index using `insert`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 136,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['i', 'n', 's', 'e', 'r', 't', 'A', 'd', 'd']\n"
     ]
    }
   ],
   "source": [
    "l.insert(0, \"i\")\n",
    "l.insert(1, \"n\")\n",
    "l.insert(2, \"s\")\n",
    "l.insert(3, \"e\")\n",
    "l.insert(4, \"r\")\n",
    "l.insert(5, \"t\")\n",
    "\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 136,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### Remove\n",
    "Remove first element with specific value using 'remove'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 138
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['i', 'n', 's', 'e', 'r', 't', 'd', 'd']\n"
     ]
    }
   ],
   "source": [
    "l.remove(\"A\")\n",
    "\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 139
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Remove an element at a specific location using `del`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 140,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['i', 'n', 's', 'e', 'r', 't']\n"
     ]
    }
   ],
   "source": [
    "del l[7]\n",
    "del l[6]\n",
    "\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question\n",
    "\n",
    "\n",
    "Print the length of a given list like [9,5,1,2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "#Write your solution here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Execute the next cell to see a sample solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "hideCode": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "print(len([9,5,1,2])\n"
     ]
    }
   ],
   "source": [
    "print(\"\"\"print(len([9,5,1,2])\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check if 3 belong to this list [6,9,5,3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#Write your solution here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Execute the next cell to see a sample solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {
    "hideCode": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     3 in [6,9,5,3]\n",
      "\n",
      "The result of this instruct is boolean \n"
     ]
    }
   ],
   "source": [
    "print(\"\"\"     3 in [6,9,5,3]\n",
    "\n",
    "The result of this instruct is boolean \"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 140,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Tuples"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 140
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "Tuples are like lists, except that they cannot be modified once created, that is they are *immutable*. \n",
    "\n",
    "In Python, tuples are created using the syntax `(..., ..., ...)`, or even `..., ...`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 143
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10, 20) <class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "point = (10, 20)\n",
    "\n",
    "print(point, type(point))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 144,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(10, 20) <class 'tuple'>\n"
     ]
    }
   ],
   "source": [
    "point = 10, 20\n",
    "\n",
    "print(point, type(point))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 144,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Unpacking tuples\n",
    "\n",
    "We can unpack a tuple by assigning it to a comma-separated list of variables:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 146,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = 10\n",
      "y = 20\n"
     ]
    }
   ],
   "source": [
    "x, y = point\n",
    "\n",
    "print(\"x =\", x)\n",
    "print(\"y =\", y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 146,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### Tuples are Inmutable \n",
    "\n",
    "If we try to assign a new value to an element in a tuple we get an error:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 148,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'point' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-66-ac1c641a5dca>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpoint\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'point' is not defined"
     ]
    }
   ],
   "source": [
    "point[0] = 20"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 148,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Dictionaries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 148
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "Dictionaries are also like lists, except that each element is a key-value pair. The syntax for dictionaries is `{key1 : value1, ...}`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 151
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'dict'>\n",
      "{'parameter1': 1.0, 'parameter3': 3.0, 'parameter2': 2.0}\n"
     ]
    }
   ],
   "source": [
    "params = {\"parameter1\" : 1.0,\n",
    "          \"parameter2\" : 2.0,\n",
    "          \"parameter3\" : 3.0,}\n",
    "\n",
    "print(type(params))\n",
    "print(params)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 152
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "parameter1 = 1.0\n",
      "parameter2 = 2.0\n",
      "parameter3 = 3.0\n"
     ]
    }
   ],
   "source": [
    "print(\"parameter1 = \" + str(params[\"parameter1\"]))\n",
    "print(\"parameter2 = \" + str(params[\"parameter2\"]))\n",
    "print(\"parameter3 = \" + str(params[\"parameter3\"]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 153,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "parameter1 = A\n",
      "parameter2 = B\n",
      "parameter3 = 3.0\n",
      "parameter4 = D\n"
     ]
    }
   ],
   "source": [
    "params[\"parameter1\"] = \"A\"\n",
    "params[\"parameter2\"] = \"B\"\n",
    "\n",
    "# add a new entry\n",
    "params[\"parameter4\"] = \"D\"\n",
    "\n",
    "print(\"parameter1 = \" + str(params[\"parameter1\"]))\n",
    "print(\"parameter2 = \" + str(params[\"parameter2\"]))\n",
    "print(\"parameter3 = \" + str(params[\"parameter3\"]))\n",
    "print(\"parameter4 = \" + str(params[\"parameter4\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 153,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Now it is time to do Exercise 2.1.a.\n",
    "\n",
    "\n",
    "See for the exercise subfolder.\n",
    "  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 153,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Control Flow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 153,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Conditional statements: if, elif, else"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 153
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "The Python Syntax for conditional execution of code use the keywords `if`, `elif` (else if), `else`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 158,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "statement1 is True\n"
     ]
    }
   ],
   "source": [
    "statement1 = True\n",
    "statement2 = False\n",
    "\n",
    "if statement1:\n",
    "    print(\"statement1 is True\")\n",
    "\n",
    "elif statement2:\n",
    "    print(\"statement2 is True\")\n",
    "    \n",
    "else:\n",
    "    print(\"statement1 and statement2 are False\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 158,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Blocks are defined by indention\n",
    "\n",
    "For the first time, here we encounted a peculiar and unusual aspect of the Python programming language: Program blocks are defined by their indentation level. \n",
    "\n",
    "Compare to the equivalent C code:\n",
    "\n",
    "    if (statement1)\n",
    "    {\n",
    "        printf(\"statement1 is True\\n\");\n",
    "    }\n",
    "    else if (statement2)\n",
    "    {\n",
    "        printf(\"statement2 is True\\n\");\n",
    "    }\n",
    "    else\n",
    "    {\n",
    "        printf(\"statement1 and statement2 are False\\n\");\n",
    "    }\n",
    "\n",
    "In C blocks are defined by the enclosing curly brakets `{` and `}`. And the level of indentation (white space before the code statements) does not matter (completely optional). \n",
    "\n",
    "But in Python, the extent of a code block is defined by the indentation level (usually a tab or say four white spaces). This means that we have to be careful to indent our code correctly, or else we will get syntax errors. \n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 158,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### IF Example - Blocks by indention"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 161
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "both statement1 and statement2 are True\n"
     ]
    }
   ],
   "source": [
    "statement1 = statement2 = True\n",
    "\n",
    "if statement1:\n",
    "    if statement2:\n",
    "        print(\"both statement1 and statement2 are True\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 162
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "both statement1 and statement2 are True\n"
     ]
    }
   ],
   "source": [
    "# Bad indentation!\n",
    "if statement1:\n",
    "    if statement2:      \n",
    "        print(\"both statement1 and statement2 are True\")  # this line is not properly indented"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 163
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "statement1 = False \n",
    "\n",
    "if statement1:\n",
    "    print(\"printed if statement1 is True\")\n",
    "    \n",
    "    print(\"still inside the if block\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 164,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "now outside the if block\n"
     ]
    }
   ],
   "source": [
    "if statement1:\n",
    "    print(\"printed if statement1 is True\")\n",
    "    \n",
    "print(\"now outside the if block\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 164,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Loops"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 164
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "In Python, loops can be programmed in a number of different ways. The most common is the `for` loop, which is used together with iterable objects, such as lists. The basic syntax is:\n",
    "\n",
    "\n",
    "### `for` loops:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 167,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "[1, 2, 3]\n"
     ]
    }
   ],
   "source": [
    "for x in [1,2,3]:\n",
    "    print(x)\n",
    "y=[1,2,3]\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 167,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Counting `for` loops\n",
    "\n",
    "The `for` loop iterates over the elements of the supplied list, and executes the containing block once for each element. Any kind of list can be used in the `for` loop. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 169
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "for x in range(6): # by default range start at 0\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 170
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Note: `range(4)` does not include 4 !"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 171
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-3\n",
      "-2\n",
      "-1\n",
      "0\n",
      "1\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "for x in range(-3,3):\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 172,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data\n",
      "science\n",
      "with\n",
      "python\n"
     ]
    }
   ],
   "source": [
    "for word in [\"data\", \"science\", \"with\", \"python\"]:\n",
    "    print(word)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 172,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Iterating over Dictionaries\n",
    "\n",
    "To iterate over key-value pairs of a dictionary:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 174
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "parameter1 = A\n",
      "parameter3 = 3.0\n",
      "parameter4 = D\n",
      "parameter2 = B\n"
     ]
    }
   ],
   "source": [
    "for key, value in params.items():\n",
    "    print(key + \" = \" + str(value))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 175
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Sometimes it is useful to have access to the indices of the values when iterating over a list. We can use the `enumerate` function for this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 176,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 -3\n",
      "1 -2\n",
      "2 -1\n",
      "3 0\n",
      "4 1\n",
      "5 2\n"
     ]
    }
   ],
   "source": [
    " for idx, x in enumerate(range(-3,3)):\n",
    "    print(idx, x) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 176,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### List comprehensions: Creating lists using `for` loops\n",
    "\n",
    "A convenient and compact way to initialize lists:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 178
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 4, 9, 16]\n"
     ]
    }
   ],
   "source": [
    "l1 = [x**2 for x in range(0,5)]\n",
    "\n",
    "print(l1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 179
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "List comprehensions can be conditional (and hence very powerful especially when working with data structures!)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 180,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 4]\n"
     ]
    }
   ],
   "source": [
    "l1 = [x**2 for x in range(0,5) if x<3]\n",
    "\n",
    "print(l1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 180,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### `while` loops"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 182
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "done\n"
     ]
    }
   ],
   "source": [
    "i = 0\n",
    "\n",
    "while i < 5:\n",
    "    print(i)\n",
    "    \n",
    "    i = i + 1\n",
    "    \n",
    "print(\"done\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 183,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Note that the `print(\"done\")` statement is not part of the `while` loop body because of the difference in indentation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 183,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 183
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "A function in Python is defined using the keyword `def`, followed by a function name, a signature within parenthises `()`, and a colon `:`. The following code, with one additional level of indentation, is the function body."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 186
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "def func0():   \n",
    "    print(\"test\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 187,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test\n"
     ]
    }
   ],
   "source": [
    "func0()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 187,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Documenting a Function"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 187
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "Optionally, but highly recommended, we can define a so called \"docstring\", which is a description of the functions purpose and behaivor. The docstring should follow directly after the function definition, before the code in the function body."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 190
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "def func1(s):\n",
    "    \"\"\"\n",
    "    Print a string 's' and tell how many characters it has \n",
    "    \"\"\"\n",
    "    \n",
    "    print(s + \" has \" + str(len(s)) + \" characters\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 191
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function func1 in module __main__:\n",
      "\n",
      "func1(s)\n",
      "    Print a string 's' and tell how many characters it has\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(func1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 192,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test has 4 characters\n"
     ]
    }
   ],
   "source": [
    "func1(\"test\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 192,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "##  Returning values"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 192
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "Functions that returns a value use the `return` keyword to return __any object or function__:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 195
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "def square(x):\n",
    "    \"\"\"\n",
    "    Return the square of x.\n",
    "    \"\"\"\n",
    "    return x ** 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 196,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "16"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "square(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 196,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Returning Multiple Values\n",
    "We can return multiple values from a function using tuples (see above):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 198
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "def powers(x):\n",
    "    \"\"\"\n",
    "    Return a few powers of x.\n",
    "    \"\"\"\n",
    "    return x ** 2, x ** 3, x ** 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 199
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'tuple'>\n",
      "(9, 27, 81)\n",
      "9\n"
     ]
    }
   ],
   "source": [
    "h=powers(3)\n",
    "print(type(h))\n",
    "print(h)\n",
    "print(h[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 200,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "27\n"
     ]
    }
   ],
   "source": [
    "x2, x3, x4 = powers(3)\n",
    "\n",
    "print(x3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 200,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Default argument and keyword arguments"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 200
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "In a definition of a function, we can give default values to the arguments the function takes:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 203
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "def myfunc(x, p=2, debug=False):\n",
    "    if debug:\n",
    "        print(\"evaluating myfunc for x = \" + str(x) + \" using exponent p = \" + str(p))\n",
    "    return x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 204
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "If we don't provide a value of the `debug` argument when calling the the function `myfunc` it defaults to the value provided in the function definition:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 205
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "myfunc(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 206,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "evaluating myfunc for x = 5 using exponent p = jadfs\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "5"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "myfunc(5, debug=True, p=\"jadfs\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 206,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Keyword Argument\n",
    "If we explicitly list the name of the arguments in the function calls, they do not need to come in the same order as in the function definition.\n",
    "\n",
    "This is called *keyword* arguments, and is often very useful in functions that takes a lot of optional arguments."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 208,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "evaluating myfunc for x = 7 using exponent p = 3\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "7"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "myfunc(p=3, debug=True, x=7)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 208,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Unnamed functions (lambda function)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 208
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "In Python we can also create unnamed functions, using the `lambda` keyword:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 211
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "f1 = lambda x: x**2\n",
    "    \n",
    "# is equivalent to \n",
    "\n",
    "def f2(x):\n",
    "    return x**2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 212,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(4, 4)"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "f1(2), f2(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 212,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### (Lambda) Functions as Argument\n",
    "\n",
    "This technique is useful for example when we want to pass a simple function as an argument to another function, like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 214
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<map at 0x10836a550>"
      ]
     },
     "execution_count": 90,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# map is a built-in python function, that applys a given funtion to an iterable and returns the results\n",
    "# map(function, iterable, ...)\n",
    "map(lambda x: x**2, range(-3,4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 215,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[9, 4, 1, 0, 1, 4, 9]"
      ]
     },
     "execution_count": 122,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# in python 3 we can use `list(...)` to convert the iterator to an explicit list\n",
    "list(map(lambda x: x**2, range(-3,4)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 215,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "**Now it would be a good time to do Exercise 2.1.b**\n",
    "\n",
    "See in the exercise subfolder ([local](exercises/Exercise%20DSiP-2-1-Python%20Standard%20Data%20Structures.ipynb)|[online](http://nbviewer.ipython.org/github/mgrani/LODA-lecture-notes-on-data-analysis/blob/master/I-Data-Science-in-Python/exercises/Exercise%20DSiP-2-1-Python%20Standard%20Data%20Structures.ipynb))."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Practice"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 1\n",
    "Write a Python function that can calculate the length of a given string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "unexpected EOF while parsing (<ipython-input-123-04f2fe160e59>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-123-04f2fe160e59>\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m    #write your code here\u001b[0m\n\u001b[0m                         ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unexpected EOF while parsing\n"
     ]
    }
   ],
   "source": [
    "def s_length(string):\n",
    "    #write your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Execute the next cell to test your solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {
    "hideCode": true
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 's_length' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-124-6fa9cd8be4aa>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m     \u001b[0;32massert\u001b[0m \u001b[0ms_length\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"python\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m6\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      7\u001b[0m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"success\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      8\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mAssertionError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 's_length' is not defined"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "import traceback\n",
    "\n",
    "\n",
    "try:\n",
    "    assert s_length(\"python\") == 6\n",
    "    print(\"success\")\n",
    "except AssertionError:\n",
    "    print('try again')\n",
    "    \n",
    "solution =\"\"\"def s_length(string):\n",
    "    c = 0\n",
    "    for char in string:\n",
    "        c += 1\n",
    "    return c\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Execute the next cell to see the solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {
    "hideCode": true
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'solution' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-125-0476c3ec12e1>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msolution\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'solution' is not defined"
     ]
    }
   ],
   "source": [
    "print(solution)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 2\n",
    "Write a function that print a single string from two strings, separated by a space and switch the first character of each string.\n",
    "\n",
    "Sample String : 'abc', 'xyz' \n",
    "Expected Result : 'xbc ayz'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "unexpected EOF while parsing (<ipython-input-126-a37422b14840>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-126-a37422b14840>\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m    #write your code here\u001b[0m\n\u001b[0m                         ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unexpected EOF while parsing\n"
     ]
    }
   ],
   "source": [
    "def char_mix(a, b):\n",
    "    #write your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Execute the next cell to test your solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {
    "hideCode": true
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'char_mix' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-127-49edf9e4bdfd>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m     \u001b[0;32massert\u001b[0m \u001b[0mchar_mix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"abc\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\"jhg\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"jbc ahg\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      7\u001b[0m     \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"success\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      8\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mAssertionError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mNameError\u001b[0m: name 'char_mix' is not defined"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "import traceback\n",
    "\n",
    "\n",
    "try:\n",
    "    assert char_mix(\"abc\",\"jhg\") == \"jbc ahg\"\n",
    "    print(\"success\")\n",
    "except AssertionError:\n",
    "    print('try again')\n",
    "    \n",
    "sol =\"\"\"def char_mix(a, b):\n",
    "  mix_a = b[:1] + a[1:]\n",
    "  mix_b = a[:1] + b[1:]\n",
    "  return mix_a + ' ' + mix_b\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Execute the next cell to see the solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {
    "hideCode": true
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'sol' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-128-1231917d0109>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msol\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'sol' is not defined"
     ]
    }
   ],
   "source": [
    "print(sol)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 215,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Classes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 218,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "\n",
    "\n",
    "Classes are the key features of object-oriented programming.\n",
    "\n",
    "A class is a structure for representing an object and the operations that can be performed on the object. \n",
    "\n",
    "A class can contain *attributes* (variables) and *methods* (functions).\n",
    "\n",
    "A class is defined using the `class` keyword plus a number of class method definitions (a function in a class).\n",
    "\n",
    "* Each class method should have **an argurment `self`** as it first argument. This object is a self-reference.\n",
    "\n",
    "* Some class method names have special meaning, for example:\n",
    "\n",
    " * `__init__`: The name of the method that is invoked when the object is first created.\n",
    " * `__str__` : A method that is invoked when a simple string representation of the class is needed, as for example when printed.\n",
    " * There are many more, see http://docs.python.org/2/reference/datamodel.html#special-method-names"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 218,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "class Point:\n",
    "    \"\"\"\n",
    "    Simple class for representing a point in a Cartesian coordinate system.\n",
    "    \"\"\"\n",
    "    \n",
    "    def __init__(self, x, y):\n",
    "        \"\"\"\n",
    "        Create a new Point at x, y.\n",
    "        \"\"\"\n",
    "        self.x = x\n",
    "        self.y = y\n",
    "        \n",
    "    def translate(self, dx, dy):\n",
    "        \"\"\"\n",
    "        Translate the point by dx and dy in the x and y direction.\n",
    "        \"\"\"\n",
    "        self.x += dx\n",
    "        self.y += dy\n",
    "        \n",
    "    def __str__(self):\n",
    "        return(\"Point at [%f, %f]\" % (self.x, self.y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 218,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Instance Creation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 218
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "To create a new instance of a class:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 222
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Point at [0.000000, 0.000000]\n"
     ]
    }
   ],
   "source": [
    "p1 = Point(0, 0) # this will invoke the __init__ method in the Point class\n",
    "\n",
    "print(p1)         # this will invode the __str__ method"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 223
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "To invoke a class method in the class instance `p`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 224
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Point at [0.250000, 1.500000]\n",
      "Point at [1.000000, 1.000000]\n"
     ]
    }
   ],
   "source": [
    "p2 = Point(1, 1)\n",
    "\n",
    "p1.translate(0.25, 1.5)\n",
    "\n",
    "print(p1)\n",
    "print(p2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 225,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Note that calling class methods can modifiy the state of that particular class instance, but does not effect other class instances or any global variables.\n",
    "\n",
    "That is one of the nice things about object-oriented design: code such as functions and related variables are grouped in separate and independent entities. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Practice"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Exercise 1\n",
    "Write a class named Circle created by a radius and two methods which will compute the perimeter and the area of a circle."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class Circle():\n",
    "    #write your code here and then remove the `pass`\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Execute the next cell to test your solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "hideCode": true
   },
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "object() takes no parameters",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-3-0c7e117acf72>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      2\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtraceback\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mNew_Circle\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mCircle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      5\u001b[0m \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      6\u001b[0m     \u001b[1;32massert\u001b[0m \u001b[0mNew_Circle\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marea\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;36m50.24\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mTypeError\u001b[0m: object() takes no parameters"
     ]
    }
   ],
   "source": [
    "import sys\n",
    "import traceback\n",
    "\n",
    "New_Circle = Circle(4)\n",
    "try:\n",
    "    assert New_Circle.area() == 50.24\n",
    "    assert New_Circle.perimeter() == 25.12\n",
    "    print(\"success\")\n",
    "except AssertionError:\n",
    "    print('try again')\n",
    "    \n",
    "sol1 =\"\"\"class Circle():\n",
    "    def __init__(self, r):\n",
    "        self.radius = r\n",
    "\n",
    "    def area(self):\n",
    "        return self.radius**2*3.14\n",
    "    \n",
    "    def perimeter(self):\n",
    "        return 2*self.radius*3.14\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Execute the next cell to see the solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "hideCode": true
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'sol1' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-4-cc7f2a346d42>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msol1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'sol1' is not defined"
     ]
    }
   ],
   "source": [
    "print(sol1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 225,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Creating Modules"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 225,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "One of the most important concepts in good programming is to reuse code and avoid repetitions.\n",
    "\n",
    "The idea is to write functions and classes with a well-defined purpose and scope, and reuse these instead of repeating similar code in different part of a program (modular programming). The result is usually that readability and maintainability of a program is greatly improved. What this means in practice is that our programs have fewer bugs, are easier to extend and debug/troubleshoot. \n",
    "\n",
    "Python supports modular programming at different levels. Functions and classes are examples of tools for low-level modular programming. Python modules are a higher-level modular programming construct, where we can collect related variables, functions and classes in a module. A python module is defined in a python file (with file-ending `.py`), and it can be made accessible to other Python modules and programs using the `import` statement. \n",
    "\n",
    "Consider the following example: the file `mymodule.py` contains simple example implementations of a variable, function and a class:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 225,
     "slide_helper": "subslide_end",
     "slide_type": "subslide"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing mymodule.py\n"
     ]
    }
   ],
   "source": [
    "%%file mymodule.py\n",
    "\"\"\"\n",
    "Example of a python module. Contains a variable called my_variable,\n",
    "a function called my_function, and a class called MyClass.\n",
    "The code is stored in mymodule.py through using the %%file magic\n",
    "\"\"\"\n",
    "\n",
    "my_variable = 0\n",
    "\n",
    "def my_function():\n",
    "    \"\"\"\n",
    "    Example function\n",
    "    \"\"\"\n",
    "    return my_variable\n",
    "    \n",
    "class MyClass:\n",
    "    \"\"\"\n",
    "    Example class.\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(self):\n",
    "        self.variable = my_variable\n",
    "        \n",
    "    def set_variable(self, new_value):\n",
    "        \"\"\"\n",
    "        Set self.variable to a new value\n",
    "        \"\"\"\n",
    "        self.variable = new_value\n",
    "        \n",
    "    def get_variable(self):\n",
    "        return self.variable"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 225,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Exceptions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 225,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "In Python errors are managed with a special language construct called \"Exceptions\". When errors occur exceptions can be raised, which interrupts the normal program flow and fallback to somewhere else in the code where the closest try-except statements is defined.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 225,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "##  Generating Exceptions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 225
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "To generate an exception we can use the `raise` statement, which takes an argument that must be an instance of the class `BaseExpection` or a class derived from it. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 233
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "ename": "Exception",
     "evalue": "description of the error",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mException\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-136-8f47ba831d5a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"description of the error\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mException\u001b[0m: description of the error"
     ]
    }
   ],
   "source": [
    "raise Exception(\"description of the error\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 234,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "A typical use of exceptions is to abort functions when some error condition occurs, for example:\n",
    "\n",
    "    def my_function(arguments):\n",
    "    \n",
    "        if not verify(arguments):\n",
    "            raise Expection(\"Invalid arguments\")\n",
    "        \n",
    "        # rest of the code goes here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 234,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Catching Exception"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 234
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "To gracefully catch errors that are generated by functions and class methods, or by the Python interpreter itself, use the `try` and  `except` statements:\n",
    "\n",
    "    try:\n",
    "        # normal code goes here\n",
    "    except:\n",
    "        # code for error handling goes here\n",
    "        # this code is not executed unless the code\n",
    "        # above generated an error\n",
    "\n",
    "For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 237,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "subslide_end",
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test\n",
      "Caught an expection\n"
     ]
    }
   ],
   "source": [
    "\n",
    "try:\n",
    "    print(\"test\")\n",
    "    # generate an error: the variable test is not defined\n",
    "    print(test)\n",
    "except:\n",
    "    print(\"Caught an expection\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 237,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## Message of an Exception"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 237
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "\n",
    "To get information about the error, we can access the `Exception` class instance that describes the exception by using for example:\n",
    "\n",
    "    except Exception as e:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 240
    },
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test\n",
      "Caught an exception:name 'test' is not defined\n"
     ]
    }
   ],
   "source": [
    "try:\n",
    "    print(\"test\")\n",
    "    # generate an error: the variable test is not defined\n",
    "    print(test)\n",
    "except Exception as e:\n",
    "    print(\"Caught an exception:\" + str(e))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 240
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "Print the stack trace of an exception"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 240,
     "slide_helper": "subslide_end"
    },
    "slide_helper": "slide_end",
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test\n",
      "Caught an exception:name 'test' is not defined\n",
      "And here comes the Traceback:\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Traceback (most recent call last):\n",
      "  File \"<ipython-input-96-1205d0fe34a1>\", line 6, in tb_test\n",
      "    print(test)\n",
      "NameError: name 'test' is not defined\n"
     ]
    }
   ],
   "source": [
    "import traceback\n",
    "def tb_test():\n",
    "    try:\n",
    "        print(\"test\")\n",
    "        # generate an error: the variable test is not defined\n",
    "        print(test)\n",
    "    except Exception as e:\n",
    "        print(\"Caught an exception:\" + str(e))\n",
    "        print(\"And here comes the Traceback:\")\n",
    "        traceback.print_exc()\n",
    "\n",
    "tb_test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "heading_collapsed": false,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 240,
     "slide_type": "subslide"
    },
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Further reading"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 240
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "\n",
    "\n",
    "* http://www.python.org - The official web page of the Python programming language.\n",
    "* http://www.python.org/dev/peps/pep-0008 - Style guide for Python programming. Highly recommended. \n",
    "* http://www.greenteapress.com/thinkpython/ - A free book on Python programming.\n",
    "* [Python Essential Reference](http://www.amazon.com/Python-Essential-Reference-4th-Edition/dp/0672329786) - A good reference book on Python programming."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 240
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "source": [
    "### Versions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "collapsed": true,
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 240
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "import IPython"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {
    "internals": {
     "frag_helper": "fragment_end",
     "frag_number": 240
    },
    "slideshow": {
     "slide_type": "-"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This notebook was evaluated with: Python 3.5.2 |Anaconda custom (x86_64)| (default, Jul  2 2016, 17:52:12) \n",
      "[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.28)] and IPython 5.1.0.\n"
     ]
    }
   ],
   "source": [
    "print(\"This notebook was evaluated with: Python %s and IPython %s.\" % (sys.version, IPython.__version__))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "celltoolbar": "Hide code",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "toc": {
   "colors": {
    "hover_highlight": "#DAA520",
    "running_highlight": "#FF0000",
    "selected_highlight": "#FFD700"
   },
   "moveMenuLeft": true,
   "nav_menu": {
    "height": "512px",
    "width": "252px"
   },
   "navigate_menu": true,
   "number_sections": true,
   "sideBar": true,
   "threshold": 4,
   "toc_cell": false,
   "toc_section_display": "block",
   "toc_window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
